/**
  ******************************************************************************
  * File Name          : terminal.c
  * Description        : Code for terminal applications
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "tskcfg.h"
#include "bsp.h"
#include "edct.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TTY_RXBUF_MAXLEN           40
#define TTYRECV_QUE_LENGTH         3
#define TTYRECV_QUE_ITEMSIZE       sizeof(tty_recvbuftype)

typedef enum
{
	TTY_HEADER1  = 0u,
	TTY_HEADER2,
	TTY_PAYLOAD,
	TTY_0A,
}tty_recvstattype;

typedef struct
{
	char buf[TTY_RXBUF_MAXLEN];
	uint8_t len;
}tty_recvbuftype;

typedef struct
{
	tty_recvstattype stat;
}tty_recvctrltype;

QueueHandle_t        ttyrecv_qhd;
static StaticQueue_t ttyrecv_stru;
static uint8_t       ttyrecv_area[ TTYRECV_QUE_LENGTH * TTYRECV_QUE_ITEMSIZE ];

TaskHandle_t xTerminal_Thd = NULL;
StaticTask_t xTerminal_Tcb;
StackType_t  xTerminal_Stk[ TTY_STACK_SIZE ];

static tty_recvctrltype   tty_rcvctrl;
static tty_recvbuftype    tty_isrbuf;
tty_recvbuftype    tty_rcvbuf;

uint8_t test[TTY_RXBUF_MAXLEN];
uint16_t testlen = 0;

static void cmd_id(const char *buf)
{
  uint8_t err;
	uint8_t sftype;
	
	if(strcmp(buf, Edct_RunPara.did) == 0)
  {
    _printf("ID::same did\r\n");
    return;
  }
  
  err = Route_ParseDID(buf, NULL);
	if(err != 0)
	{
		_printf("ID::error--%d\r\n", err);
		return;
	}
  
  _printf("ID::success--%s\r\n", buf);
	
	strncpy(Edct_RunPara.did, buf, ROUTE_DID_BUFLEN);
	
	if(Storage_qhd != NULL)
	{
		sftype = 1;
		xQueueSend(Storage_qhd, &sftype, 1000);
	}
}

static void cmd_tvoc(const char *buf)
{
	uint8_t sftype;
	
	if(buf[0] == '1')
	{
		Edct_RunPara.tvoc_en = 1;
		_printf("TVOC is Enable\r\n");
	}
	else if(buf[0] == '0')
	{
		Edct_RunPara.tvoc_en = 0;
		_printf("TVOC is Disable!\r\n");
	}
	else
	{
		_printf("TVOC Error!\r\n");
		return;
	}
		
	if(Storage_qhd != NULL)
	{
		sftype = 1;
		xQueueSend(Storage_qhd, &sftype, 1000);
	}
}

static void cmd_pres(const char *buf)
{
	uint8_t sftype;
	
	if(buf[0] == '1')
	{
		Edct_RunPara.sdp810_en = 1;
		_printf("PRES is Enable\r\n");
	}
	else if(buf[0] == '0')
	{
		Edct_RunPara.sdp810_en = 0;
		_printf("PRES is Disable!\r\n");
	}
	else
	{
		_printf("PRES Error!\r\n");
		return;
	}
		
	if(Storage_qhd != NULL)
	{
		sftype = 1;
		xQueueSend(Storage_qhd, &sftype, 1000);
	}
}

void vTerminal_Task( void * pvParameters )
{
	const char *p;
	ttyrecv_qhd = xQueueCreateStatic(TTYRECV_QUE_LENGTH,
	                                 TTYRECV_QUE_ITEMSIZE,
	                                 ttyrecv_area,
	                                 &ttyrecv_stru);
	while(1)
	{
		if(xQueueReceive(ttyrecv_qhd, &tty_rcvbuf, portMAX_DELAY) == pdTRUE)
		{
      p = strstr( tty_rcvbuf.buf, "ID:");
			if( p != NULL)
			{
				cmd_id(p+3);
			}
			
			p = strstr( tty_rcvbuf.buf, "TVOC:");
			if( p != NULL)
			{
				cmd_tvoc(p+5);
			}
			
      p = strstr( tty_rcvbuf.buf, "PRES:");
			if( p != NULL)
			{
				cmd_pres(p+5);
			}
      
			_printf("%s\r\n", tty_rcvbuf.buf);
		}
	}
}

void Terminal_RecvIsr(uint8_t dat)
{
	static uint32_t count;
	
	switch(tty_rcvctrl.stat)
	{
		case TTY_HEADER1:
			if(dat == ';')
			{
				tty_rcvctrl.stat = TTY_HEADER2;
			}
			break;
		
		case TTY_HEADER2:
			if(dat == ';')
			{
				tty_rcvctrl.stat = TTY_PAYLOAD;
				count = 0;
			}
			else
			{
				tty_rcvctrl.stat = TTY_HEADER1;
			}
			break;
		
		case TTY_PAYLOAD:
			if(dat == 0x0du)
			{
				tty_rcvctrl.stat = TTY_0A;
			}
			else
			{
				tty_isrbuf.buf[count++] = dat;
				if(count > (TTY_RXBUF_MAXLEN-4))
				{
					tty_rcvctrl.stat = TTY_HEADER1;
				}
			}
			break;
		
		case TTY_0A:
			if(dat == 0x0au)
			{
				tty_isrbuf.buf[count] = 0;
				tty_isrbuf.len = count;
				if(ttyrecv_qhd != NULL)
				{
					xQueueSendFromISR(ttyrecv_qhd, &tty_isrbuf, NULL);
				}
			}
			tty_rcvctrl.stat = TTY_HEADER1;
			break;
		
		default:
			tty_rcvctrl.stat = TTY_HEADER1;
			break;
	}
}

void Terminal_BreakIsr(void)
{
	tty_rcvctrl.stat = TTY_HEADER1;
}
